#include "mytcpsocket.h"
#include <QDebug>

MyTcpSocket::MyTcpSocket(QObject *parent): QTcpSocket(parent)
{
    connect(this, &MyTcpSocket::readyRead, this, &MyTcpSocket::readPacket);
}

void MyTcpSocket::sendTLV(TaskType type, int len, const QByteArray &msg)
{
    if (!isOpen() || !isWritable()) {
        qWarning() << "TcpSocket is not connected";
        return;
    }
    if (msg.isEmpty()) {
        qWarning() << "msg is empty";
        return;
    }

    QByteArray tlv;
    // 将4字节type写入tlv中
    tlv.append(reinterpret_cast<const char *>(&type), sizeof(int));
    // 将4字节len写入tlv中
    tlv.append(reinterpret_cast<const char *>(&len), sizeof(int));
    qDebug() << "msg:" << msg;
    tlv.append(msg);

    // 发送tlv
    sendn(tlv, sizeof(int) * 2 + len);
    flush();
}

void MyTcpSocket::readPacket()
{
    qDebug()<<"开始读取接受的数据";
    // 循环处理，直到没有完整数据包可用
    while (1) {
        if (m_expectedBodySize == 0) {//如果期待数据为0，说明还没开始读到长度字符串
            // 阶段1: 等待并读取头部 (两个int，共8字节)
           // qDebug()<<"目前有"<<bytesAvailable()<<"可读";
            if (bytesAvailable() < 8) {
                return; // 头部数据不完整，等待下次数据到达
            }

            // 读取头部
            recvn((char*)&m_packet._type, sizeof(int));
            recvn((char*)&m_packet._length, sizeof(int));

            qDebug()<<"type:" << m_packet._type<<endl;
            qDebug()<<"length:" << m_packet._length<<endl;

            m_expectedBodySize = m_packet._length;//设置数据长度为TLV.length

            // 可选：验证数据长度是否合理
            if (m_expectedBodySize < 0) {
                // 处理错误：无效的数据长度
                qCritical() << "Packet.length is negative";
                return;
            }
        }
        // 阶段2: 检查是否有足够的数据体
        if (bytesAvailable() < m_expectedBodySize) {
            return; // 数据体不完整，等待下次数据到达
        }
        // 阶段3: 读取完整的数据体
        QByteArray msg;
        msg.resize(m_expectedBodySize);
        int ret = recvn(msg.data(), m_expectedBodySize);
        if (ret < m_expectedBodySize) {
            qWarning() << "Expect" << m_expectedBodySize << "bytes but only recv" << ret << "bytes.";
        }
        m_packet._msg = msg;
//        qDebug()<<"msg:" <<m_packet._msg<<endl;
        emit readPacketFinished(m_packet);//发射读取完成信号，传出读取完成的packdet，交给应用层处理
        // 重置状态，准备处理下一个消息
        clear();
    }
}

int MyTcpSocket::sendn(QByteArray buf, int len)
{
    int left = len;
    const char *pCurr = buf.constData();
    while (left > 0) {
        int ret = write(pCurr, len);
        if (ret == -1) {
            qCritical() << "Tcp write failed";
            return len - left;
        }
        pCurr += ret;
        left -= ret;
    }
    return len;
}

int MyTcpSocket::recvn(char *buf, int len)
{
    char *pCurr = buf;
    int left = len;
    while (left > 0) {
        if (!isOpen() || !isReadable()) {
            qWarning() << "TcpSocket is not readable";
            qDebug() << "recv" << len - left << "bytes";
            return len - left;
        }
        int ret = read(pCurr, len);
        if (ret == -1) {
            qCritical() << "Tcp read error";
            qDebug() << "recv" << len - left << "bytes";
            return len - left;
        }
        pCurr += ret;
        left -= ret;
    }
    qDebug() << "recv" << len << "bytes";
    return len;
}

void MyTcpSocket::clear()
{
    m_expectedBodySize = 0;
    m_packet.clear();
}
